home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 2001 October / macformat-108.iso / Shareware / Math scientific / PsyScript / libraries / file.lib / file.lib.rsrc / TEXT_2000_Source Text.txt < prev    next >
Encoding:
Text File  |  2001-08-04  |  23.1 KB  |  719 lines

  1. property pMyContainer : "" --path to the folder that contains your experiment script
  2. property pResourcesFolderName : "Resources" -- name of the folder in which you store images etc.
  3. property pPathtoResultsFolder : "" --Full path to the folder in which results will be stored.
  4. --e.g., "MacHD:PsyScriptΔí:scripts:Experiments:Eyemovement:SPEMΔí:Results:"
  5. property pResultsFolderName : "Results"
  6. property pResultsFileRef : "" -- a place to store results before you write them to disk
  7. property psubjectID : "" --the name of the data file
  8. property pSubjectDataFile : "" --path to the data file (including the name)
  9. property pResponses : {}
  10. property pKeyState : "" --contents of every key for restoring to a previous state
  11.  
  12. property qlist : {} -- used to link the qsort helper to the sort handler
  13. -- >>  PsyScript Management Functions ***************
  14.  
  15. (* to killTheControlStrip()
  16.     tell application "Control Strip"
  17.         quit
  18.     end tell
  19. end killTheControlStrip
  20.  *)
  21.  
  22.  
  23. on quitAllExcept(appstokeepalive) --{list of app names}
  24.     try
  25.         my kill_the_control_strip()
  26.     end try
  27.     try
  28.         get the path to frontmost application --me
  29.         tell application "Finder"
  30.             set myName to the name of the result
  31.             set processesToKill to (the name of every process whose file type is "APPL" and name is not myName and creator type is not "PsyS") as list
  32.             repeat with thisApp in processesToKill
  33.                 tell application thisName to quit
  34.             end repeat
  35.             if "Finder" is not in appstokeepalive then
  36.                 quit
  37.                 set end of processesToKill to "Finder"
  38.             end if
  39.             return processesToKill
  40.         end tell
  41.     end try
  42. end quitAllExcept
  43.  
  44. to initialize()
  45.     --sets the filepaths to the script, resources and results folders
  46.     set pResponses to {} --initialize the response list to empty, just to be safe.
  47.     --set default picture folder    
  48.     tell application "PsyScript"
  49.         set AppleScript's text item delimiters to ""
  50.         activate
  51.         --set my container
  52.         set the_filepath to (path to me) as text
  53.         set lastColon to the offset of ":" in (the reverse of every character of the_filepath) as string
  54.         set pMyContainer to (text 1 thru -(lastColon) of the_filepath)
  55.         
  56.         --try and initialise path to resources
  57.         try
  58.             set pathToTry to pMyContainer & pResourcesFolderName & ":"
  59.             get info for file pathToTry
  60.             set default picture folder to pathToTry
  61.         on error tmsg number tnum
  62.             if tnum = -35 then
  63.                 error "could not find folder \"" & pResourcesFolderName & "\" beside this script
  64.             I was looking here:
  65.             " & pathToTry
  66.             else
  67.                 error tmsg & return & "source: initializeFilePaths" number tnum
  68.             end if
  69.         end try
  70.         --also try and initialise path to results
  71.         try
  72.             set pPathtoResultsFolder to pMyContainer & pResultsFolderName & ":"
  73.             list folder pPathtoResultsFolder --fails the try if folder does not exist
  74.         on error tmsg number tnum
  75.             try
  76.                 tell application "Finder"
  77.                     make new folder in folder pMyContainer with properties {name:pResultsFolderName}
  78.                 end tell
  79.             on error
  80.                 error "Could not find or create folder \"" & pPathtoResultsFolder & "\" beside this script.
  81.                     Create a folder called \"results\" along side the script
  82.                     (source = initialize())"
  83.             end try
  84.         end try
  85.         return default picture folder
  86.     end tell
  87. end initialize
  88.  
  89. to setPathToResources() --sets default picture folder
  90.     tell application "PsyScript"
  91.         set AppleScript's text item delimiters to ""
  92.         activate
  93.         --set my container
  94.         set the_filepath to (path to me) as text
  95.         set lastColon to the offset of ":" in (the reverse of every character of the_filepath) as string
  96.         set pMyContainer to (text 1 thru -(lastColon) of the_filepath)
  97.         --try and initialise path to resources
  98.         try
  99.             set pathToTry to pMyContainer & pResourcesFolderName & ":"
  100.             get info for file pathToTry
  101.             set default picture folder to pathToTry
  102.         on error tmsg number tnum
  103.             if tnum = -35 then
  104.                 error "could not find folder \"" & pResourcesFolderName & "\" beside this script
  105.             I was looking here:
  106.             " & pathToTry
  107.             else
  108.                 error tmsg & return & "source: setPathToResources" number tnum
  109.             end if
  110.         end try
  111.     end tell
  112. end setPathToResources
  113.  
  114. to createNewSubjectID()
  115.     --locates or creates the results folder
  116.     --gets a subject ID via dialog, checks that no corresponding file exists
  117.     --returns a subjectID
  118.     tell application "PsyScript"
  119.         activate
  120.         try
  121.             list folder pPathtoResultsFolder --fails the try if folder does not exist
  122.         on error errormessage number errorNumber
  123.             if errorNumber = -35 then
  124.                 try
  125.                     tell application "Finder"
  126.                         make new folder in folder pMyContainer with properties {name:pResultsFolderName}
  127.                     end tell
  128.                 on error
  129.                     error "Create a folder called \"results\" along side the script
  130.                     (source = createNewSubjectID)"
  131.                 end try
  132.             else
  133.                 error errormessage & return & "(source = createNewSubjectID)" number errorNumber
  134.             end if
  135.         end try
  136.         set thePrompt to "Enter your Subject ID"
  137.         set notUnique to true
  138.         repeat while notUnique
  139.             try
  140.                 display dialog thePrompt default answer ""
  141.                 set psubjectID to the text returned of the result
  142.                 if psubjectID = "" then
  143.                     set thePrompt to "Must enter at least 1 character"
  144.                 else
  145.                     set pSubjectDataFile to pPathtoResultsFolder & psubjectID as string
  146.                     tell application "Finder"
  147.                         if exists file pSubjectDataFile then --hopefully this fails (and the id is not taken)
  148.                             --was able to read that file:ask if the user want to reuse it
  149.                             display dialog "The Identifier " & psubjectID & "already exists
  150.                 Would you like to overwrite this, append new data, or choose a new ID?" buttons {"overwrite", "append", "choose new"} default button "choose new"
  151.                             set userChoice to the button returned of the result
  152.                             if userChoice is "append" then
  153.                                 exit repeat
  154.                             else if userChoice is "overwrite" then
  155.                                 set eof of file pSubjectDataFile to 0
  156.                                 exit repeat
  157.                             else
  158.                                 set thePrompt to "That Subject ID is already taken: try another"
  159.                             end if
  160.                         else
  161.                             set notUnique to false
  162.                         end if
  163.                     end tell
  164.                 end if
  165.             on error
  166.                 error "problem creating new subject ID."
  167.             end try
  168.         end repeat
  169.         return psubjectID
  170.     end tell
  171. end createNewSubjectID
  172.  
  173. to setResultsFile(pathToResultsFile)
  174.     --use this only if you do not use getvalidsubjectID
  175.     set pSubjectDataFile to pathToResultsFile
  176. end setResultsFile
  177.  
  178. to writespreadsheet(theData) --you can pass this a string, a list of strings, a record, or a list of lists! all of them work.
  179.     if class of theData is record then set theData to theData as list
  180.     if (class of theData is list) then
  181.         set oldDelims to AppleScript's text item delimiters
  182.         set AppleScript's text item delimiters to {tab}
  183.         if (class of item 1 of theData is not list) then set theData to {theData}
  184.         try
  185.             set f to open for access pSubjectDataFile with write permission
  186.             write "" to f starting at eof
  187.         on error theMessage number thenumber
  188.             if thenumber = -1409 then
  189.                 error "Probably you did not define a subject file, do this with createNewSubjectID" & ¬¨
  190.                     return & theMessage & return & "(source = writeSpreadsheet(theData))"
  191.             else
  192.                 error theMessage & return & "(source = writeSpreadsheet(theData))"
  193.             end if
  194.         end try
  195.         try
  196.             repeat with aline in theData
  197.                 try
  198.                     write "" & aline & return to f
  199.                 on error theMessage number errNumber
  200.                     set AppleScript's text item delimiters to oldDelims
  201.                     close access pSubjectDataFile
  202.                     error theMessage & return & "(source = writeSpreadsheet(theData))"
  203.                 end try
  204.             end repeat
  205.             close access pSubjectDataFile
  206.         on error theMessage number errNumber
  207.             set AppleScript's text item delimiters to oldDelims
  208.             close access pSubjectDataFile
  209.             error theMessage & return & "(source = writeSpreadsheet(theData))"
  210.         end try
  211.     else --is not a list or a record. Either already text or else a number
  212.         try --could use tanaka
  213.             set f to open for access pSubjectDataFile with write permission
  214.             write ("" & theData & return) to f starting at eof
  215.             close access f
  216.         on error
  217.             close access pSubjectDataFile
  218.             error "Failed to open, or write to " & pSubjectDataFile & return & "(source = writeSpreadsheet(theData))"
  219.         end try
  220.     end if
  221. end writespreadsheet
  222.  
  223. --use this to write companion files, files which record data to standalone files with the same base name as pSubjectDataFile
  224. to writeToCompanionFile(theData, fileSuffix) --you can pass this a string, a list of strings, a record, or a list of lists! all of them work.
  225.     set fileName to (pSubjectDataFile & fileSuffix)
  226.     if class of theData is record then set theData to theData as list
  227.     if (class of theData is list) then
  228.         set oldDelims to AppleScript's text item delimiters
  229.         set AppleScript's text item delimiters to {tab}
  230.         if (class of item 1 of theData is not list) then set theData to {theData}
  231.         try
  232.             set f to open for access fileName with write permission
  233.             write "" to f starting at eof
  234.         on error theMessage number thenumber
  235.             if thenumber = -1409 then
  236.                 error "Probably you did not define a subject file, do this with createNewSubjectID" & ¬¨
  237.                     return & theMessage & return & "(source = writeToCompanionFile(theData,fileSuffix))"
  238.             else
  239.                 error theMessage & return & "(source = writeToCompanionFile(theData,fileSuffix))"
  240.             end if
  241.         end try
  242.         try
  243.             repeat with aline in theData
  244.                 try
  245.                     write (aline as string) & return to f
  246.                 on error theMessage number errNumber
  247.                     set AppleScript's text item delimiters to oldDelims
  248.                     close access fileName
  249.                     error theMessage & return & "(source = writeToCompanionFile(theData,fileSuffix))"
  250.                 end try
  251.             end repeat
  252.             close access fileName
  253.         on error theMessage number errNumber
  254.             set AppleScript's text item delimiters to oldDelims
  255.             close access fileName
  256.             error theMessage & return & "(source = writeToCompanionFile(theData,fileSuffix))"
  257.         end try
  258.     else --is not a list or a record. Either already text or else a number
  259.         try --could use tanaka
  260.             set f to open for access fileName with write permission
  261.             write ("" & theData & return) to f starting at eof
  262.             close access f
  263.         on error
  264.             close access fileName
  265.             error "Failed to open, or write to " & fileName & return & "(source = writeToCompanionFile(theData,fileSuffix))"
  266.         end try
  267.     end if
  268. end writeToCompanionFile
  269.  
  270. --probably won't use this much - you can just call writespreadsheet() directly
  271. --it is useful if you need speed and therefore cannot afford to write the results to disk each trial.
  272.  
  273. on storeResults(newResponses, flushtoDisk)
  274.     set end of pResponses to newResponses
  275.     if flushtoDisk then
  276.         writespreadsheet(pResponses)
  277.         set pResponses to {}
  278.     end if
  279. end storeResults
  280.  
  281.  
  282. (* to cleanup()
  283.     tell application "PsyScript"
  284.         end experiment
  285.         try
  286.             close access my pSubjectDataFile
  287.         end try
  288.     end tell
  289.     tell application "Finder" to launch
  290.     tell application "Control Strip" to launch
  291. end cleanup
  292.  *)
  293.  
  294.  
  295. -- >>  LIST HANDLERS
  296. --use these to read in lists from files
  297. --modified 2001/04/23
  298. --fixed up file closing
  299. on readSpreadsheet(thefile) --takes a file path, returns a 2D array.
  300.     set outArray to {}
  301.     set oldDelims to AppleScript's text item delimiters
  302.     set AppleScript's text item delimiters to {tab}
  303.     if ":" is not in thefile then set thefile to (pMyContainer & pResourcesFolderName & ":" & thefile)
  304.     try
  305.         set f to open for access thefile
  306.     on error m number N
  307.         error "could not open the file :" & thefile & return & "Source:readspreadsheet()" & return & m number N
  308.     end try
  309.     
  310.     repeat
  311.         try
  312.             set end of outArray to (every text item of (read f before return))
  313.         on error theMessage number errNumber
  314.             try
  315.                 close access f
  316.             end try
  317.             set AppleScript's text item delimiters to oldDelims
  318.             if errNumber = -39 then -- end of file,  clean up & get out
  319.                 return outArray
  320.             else -- different type of error. Clean up & resignal user
  321.                 error theMessage & return & "readspreadsheet" number N
  322.             end if
  323.         end try
  324.     end repeat
  325.     try
  326.         close access f
  327.     end try
  328.     return outArray
  329. end readSpreadsheet
  330.  
  331. on readSpreadsheet1D(thefile) --takes a file path, returns a 1D array.
  332.     set outArray to {}
  333.     if ":" is not in thefile as string then set thefile to (pMyContainer & pResourcesFolderName & ":" & thefile)
  334.     try
  335.         set f to open for access thefile
  336.     on error m number N
  337.         error "could not open the file :" & thefile & return & "Source:readspreadsheet()" & return & m number N
  338.     end try
  339.     
  340.     repeat
  341.         try
  342.             set end of outArray to (read f before return)
  343.         on error theMessage number errNumber
  344.             try
  345.                 close access f
  346.             end try
  347.             if errNumber = -39 then -- end of file,  clean up & get out
  348.                 return outArray
  349.             else -- different type of error. Clean up & resignal user
  350.                 error theMessage & return & "readspreadsheet" number errNumber
  351.             end if
  352.         end try
  353.     end repeat
  354.     try
  355.         close access f
  356.     end try
  357.     return outArray
  358. end readSpreadsheet1D
  359.  
  360.  
  361. --initializeList(5, "0")
  362. -->{"0", "0", "0", "0", "0"}
  363. to initializeList(theCount, theContents)
  364.     set TheList to {}
  365.     repeat with N from 1 to theCount
  366.         set the end of TheList to theContents
  367.     end repeat
  368.     return TheList
  369. end initializeList
  370.  
  371. --getOffset(6, {1, 2, 3})
  372. -->-1
  373. on getOffset(what, TheList) -- return -1 if not found
  374.     repeat with i from 1 to (count of TheList)
  375.         if item i of TheList is what then return i
  376.     end repeat
  377.     return -1 --
  378. end getOffset
  379.  
  380. on sort(TheList)
  381.     set qlist to TheList
  382.     my qsort(a reference to qlist, 1, count of qlist)
  383.     return qlist
  384. end sort
  385.  
  386. --qsort is used by sort
  387. on qsort(the_list, startIndex, finishIndex)
  388.     set i to startIndex
  389.     set j to finishIndex
  390.     set mid to item ((i + j) div 2) of the_list
  391.     repeat
  392.         repeat while ((item i of the_list) < mid)
  393.             set i to i + 1
  394.         end repeat
  395.         repeat while ((item j of the_list) > mid)
  396.             set j to j - 1
  397.         end repeat
  398.         if i ‚â§ j then
  399.             set {item i of the_list, item j of the_list} to {item j of the_list, item i of the_list}
  400.             set {i, j} to {i + 1, j - 1}
  401.         end if
  402.         if i > j then exit repeat
  403.     end repeat
  404.     
  405.     if j > startIndex then qsort(the_list, startIndex, j)
  406.     if i < finishIndex then qsort(the_list, i, finishIndex)
  407. end qsort
  408.  
  409. to randomize(TheList)
  410.     repeat with i from length of TheList to 1 by -1
  411.         set current_item to (random number from 1 to i)
  412.         tell TheList -- exchange item current_item with item i
  413.             set temp to item i
  414.             set item i to item current_item
  415.             set item current_item to temp
  416.         end tell
  417.     end repeat
  418.     return TheList
  419. end randomize
  420.  
  421.  
  422. --returns the distinct elements of a list
  423. to distinct(TheList)
  424.     set outList to {}
  425.     repeat with anItem in TheList
  426.         if anItem is not in outList then
  427.             set end of outList to contents of anItem
  428.         end if
  429.     end repeat
  430.     return anItem
  431. end distinct
  432.  
  433. to union(listA, listB)
  434.     set c to listA & listB
  435.     return my distinct(c)
  436. end union
  437.  
  438. to intersection(listA, listB)
  439.     set outList to {}
  440.     repeat with anItem in listA
  441.         if (anItem is in listB) then set end of outList to contents of anItem
  442.     end repeat
  443.     return outList
  444. end intersection
  445.  
  446. to difference(listA, listB)
  447.     set outList to {}
  448.     repeat with anItem in listA
  449.         if (anItem is not in listB) then set end of outList to contents of anItem
  450.     end repeat
  451.     return outList
  452. end difference
  453.  
  454. --return insert(3, "first after 3", {1, 2, 3, 4})
  455. --{1, 2, 3, "first after 3", 4}
  456. --return insert({3, 2}, {"first after 3", "second after 2"}, {1, 2, 3, 4})
  457. --{1, 2, "second after 2", 3, "first after 3", 4}
  458. to insert(insertionAt, addingTheseItems, toThisList) --insertion item must come in reverse order!!
  459.     local N
  460.     if class of insertionAt is list then
  461.         if class of addingTheseItems is not list then
  462.             error "NewItems parameter for insertItemsAfter must be list" number -1719
  463.         else if class of toThisList is not list then
  464.             error ("originalList parameter for insertItemsAfter must be list not " & (class of toThisList as string)) number -1719
  465.         else if (count of insertionAt) ‚↠(count of addingTheseItems) then
  466.             error "insertItemsAfter says \"insertionCount  & count of NewItems must be equal\"" number -1719
  467.         else
  468.             repeat with N from 1 to count of insertionAt
  469.                 set toThisList to insert(item N of insertionAt, item N of addingTheseItems, toThisList)
  470.             end repeat
  471.             return toThisList
  472.         end if
  473.     else --inserting 1 item
  474.         copy (insertionAt as number) to x
  475.         if x = 0 then
  476.             return {} & addingTheseItems & toThisList --prepend if index is <1
  477.         else if (x ‚â• (count toThisList)) then
  478.             return (toThisList & addingTheseItems) --append if is large index
  479.         else if x = 1 then
  480.             return (item 1 of toThisList) & addingTheseItems & (items (x + 1) thru -1 of toThisList)
  481.         else
  482.             return (items 1 thru (x) of toThisList) & addingTheseItems & (items (x + 1) thru -1 of toThisList)
  483.         end if
  484.     end if
  485. end insert
  486.  
  487. --replaceItems({1, -1}, {"a", "b"}, {1, 2, 3, 4})
  488. -->{"a", 2, 3, "b"}
  489. to replaceItems(itemIndices, NewItems, originalList)
  490.     copy originalList to scratchList
  491.     if class of itemIndices is not list then
  492.         error "insertionIndices parameter for replaceItemsAt must be list" number -1719
  493.     else if class of NewItems is not list then
  494.         error "NewItems parameter for replaceItemsAt must be list" number -1719
  495.     else if class of originalList is not list then
  496.         error "originalList parameter for replaceItemsAt must be list not " & (class of originalList) number -1719
  497.     else
  498.         set N to count of itemIndices
  499.         repeat with x from 1 to N
  500.             set item (item x of itemIndices) of scratchList to (contents of item x of NewItems)
  501.         end repeat
  502.         return scratchList
  503.     end if
  504. end replaceItems
  505.  
  506.  
  507. --parsetostring({{1, 2, 3, 4}, {"a", "b", "c", "d"}}, {"‚Ä¢", return})
  508. -->1•2•3•4
  509. -->a•b•c•d
  510. on parsetostring(TheList, theDelimiters)
  511.     if (count of theDelimiters) > 1 then
  512.         (* if class of item 1 of TheList is not list then
  513.             error "you gave delimiters suggesting a 2D array but I only see 1D"
  514.         else *)
  515.         if ((count of theDelimiters) > 2) then
  516.             error "I can only do a 2D string so far"
  517.         else
  518.             set outstring to ""
  519.             repeat with aline in TheList
  520.                 set outstring to outstring & my parsetostring(aline, item 1 of theDelimiters) & item 2 of theDelimiters
  521.             end repeat
  522.         end if
  523.     else --1D
  524.         set savedTextItemDelimiters to AppleScript's text item delimiters
  525.         try
  526.             set AppleScript's text item delimiters to {theDelimiters}
  527.             set TheList to TheList as string
  528.             set AppleScript's text item delimiters to savedTextItemDelimiters
  529.             return TheList
  530.         on error errMsg number errNum from f to t partial result p
  531.             --also reset text item delimiters in case of an error:
  532.             set AppleScript's text item delimiters to savedTextItemDelimiters
  533.             --and resignal the error:
  534.             return TheList --is this a bug?
  535.             error errMsg number errNum from f to t partial result p
  536.         end try
  537.     end if
  538. end parsetostring
  539.  
  540. on stringToList(theString, theDelimiters) --
  541.     --note this will create lists for every delimiter even if the delimiter is not found
  542.     --i.e., the list is packed to a square array
  543.     
  544.     set outList to {}
  545.     set savedTextItemDelimiters to AppleScript's text item delimiters
  546.     try
  547.         set AppleScript's text item delimiters to {item 1 of theDelimiters}
  548.         set theStringAsList to every text item of theString
  549.         set AppleScript's text item delimiters to savedTextItemDelimiters
  550.     on error errMsg number errNum from f to t partial result p
  551.         --also reset text item delimiters in case of an error:
  552.         set AppleScript's text item delimiters to savedTextItemDelimiters
  553.         --and resignal the error:
  554.         error errMsg number errNum from f to t partial result p
  555.     end try
  556.     --recurse over this result if we still have delimiters in our pocket
  557.     if (count of theDelimiters) > 1 then --we are making a multidimensionalList
  558.         set newDelimiterList to items 2 through -1 of theDelimiters
  559.         repeat with aline in theStringAsList
  560.             set end of outList to my stringToList(aline, newDelimiterList)
  561.         end repeat
  562.     else
  563.         set outList to theStringAsList
  564.     end if
  565.     return outList as list
  566. end stringToList
  567.  
  568.  
  569. to subset(indices, TheList)
  570.     set outList to {}
  571.     if class of indices is not list then
  572.         return {}
  573.     else
  574.         repeat with itemIndex in indices
  575.             set end of outList to item (itemIndex as number) of TheList
  576.         end repeat
  577.         return outList
  578.     end if
  579. end subset
  580.  
  581. on removeItem(x, TheList) --at x --, theList)
  582.     -- removes any item from a list
  583.     set x to (x as number)
  584.     if x < 1 then return TheList
  585.     set numItems to count of items in TheList
  586.     if numItems is 1 then return {}
  587.     if x > numItems then return TheList
  588.     if x = 1 then
  589.         set newList to (items 2 thru -1 of TheList)
  590.     else if x = numItems then
  591.         set newList to (items 1 thru -2 of TheList)
  592.     else
  593.         set newList to (items 1 thru (x - 1) of TheList) & (items (x + 1) thru -1 of TheList)
  594.     end if
  595.     return newList
  596. end removeItem
  597.  
  598. --sample with Replacement given take:3, outof:{1, 2, 3, 4, 5, 6, 7, 8, 9}
  599. -->{3, 9, 7}
  600. --sample without Replacement given take: 3 outof: {1, 2, 3, 4, 5, 6, 7, 8, 9} 
  601. -->{3, 9, 7}
  602.  
  603. to sample(itemCount, TheList, replacing)
  604.     if itemCount > length of TheList then
  605.         error "source:sample(itemcount, thelist, replacing):
  606.         Asked for more items than exist"
  607.     else
  608.         set chosenItems to {}
  609.         if replacing then
  610.             repeat with N from 1 to itemCount
  611.                 set end of chosenItems to some item of TheList
  612.             end repeat
  613.         else
  614.             set chosenItems to items 1 thru itemCount of (my randomize(TheList))
  615.         end if
  616.         return chosenItems
  617.     end if
  618. end sample
  619.  
  620.  
  621. --makeASparseList given taking:10, outof:{}, separatedBy:4
  622. -->{5, 7, 3}
  623. on sparseRepeat given taking:numberWanted, outof:TheList, separatedBy:min
  624.     set outList to {}
  625.     set separationCheckList to {}
  626.     repeat while (count of outList) < numberWanted
  627.         set candidate to (some item of TheList)
  628.         if candidate is not in separationCheckList then
  629.             set outList to outList & candidate
  630.             set separationCheckList to separationCheckList & candidate
  631.             if (count of separationCheckList) > min then set separationCheckList to items -min thru -1 of separationCheckList
  632.         end if
  633.     end repeat
  634.     return outList
  635. end sparseRepeat
  636.  
  637. --Author = Chris Espinosa <cde@apple.com>
  638. to create_shuffled_list(listLength)
  639.     set orderedList to {}
  640.     repeat with N from 1 to listLength
  641.         set end of orderedList to N
  642.     end repeat
  643.     set shuffledList to {}
  644.     repeat listLength times
  645.         set chosenItem to 0
  646.         repeat until chosenItem is not 0
  647.             set chosenItem to some item of orderedList
  648.         end repeat
  649.         set end of shuffledList to chosenItem
  650.         set item chosenItem of orderedList to 0
  651.     end repeat
  652.     return shuffledList
  653. end create_shuffled_list
  654.  
  655.  
  656. -->create_shuffled_sublist(56, 6)
  657. --  {38, 13, 32, 52, 40, 8}
  658. to create_shuffled_sublist(totalNumberSet, listLength)
  659.     set orderedList to {}
  660.     repeat with N from 1 to totalNumberSet
  661.         set end of orderedList to N
  662.     end repeat
  663.     set shuffledList to {}
  664.     repeat listLength times
  665.         set chosenItem to 0
  666.         repeat until chosenItem is not 0
  667.             set chosenItem to some item of orderedList
  668.         end repeat
  669.         set end of shuffledList to chosenItem
  670.         set item chosenItem of orderedList to 0
  671.     end repeat
  672.     return shuffledList
  673. end create_shuffled_sublist
  674.  
  675.  
  676.  
  677. -->>KEY FUNCTIONS
  678. on saveKeyStates()
  679.     tell application "PsyScript"
  680.         set pKeyState to contents of every key
  681.     end tell
  682. end saveKeyStates
  683.  
  684. on restoreKeyStates()
  685.     tell application "PsyScript"
  686.         repeat with aKey in pKeyState
  687.             set zz to name of aKey
  688.             set noticed of key zz to noticed of aKey
  689.             set mapping of key zz to mapping of aKey
  690.         end repeat
  691.     end tell
  692. end restoreKeyStates
  693.  
  694. on setNoticed of keyName given mapping:theMapping --setNoticed of "K" given mapping:"name you want"
  695.     tell application "PsyScript"
  696.         tell key keyName
  697.             set noticed to true
  698.             set mapping to theMapping
  699.         end tell
  700.     end tell
  701. end setNoticed
  702.  
  703. to noticeKeyboard(keyList) --keyList of form {{"name","mapping"},{"name","mapping"}}
  704.     tell application "PsyScript"
  705.         set response type to keyboard response
  706.         if keyList is {} then
  707.             set noticed of every key to true
  708.         else
  709.             set noticed of every key to false
  710.             repeat with theKey in keyList
  711.                 tell key (item 1 of theKey)
  712.                     set mapping to item 2 of theKey
  713.                     set noticed to true
  714.                 end tell
  715.             end repeat
  716.         end if
  717.     end tell
  718. end noticeKeyboard
  719.